home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 210_01 / lxb.asm < prev    next >
Assembly Source File  |  1980-01-01  |  6KB  |  263 lines

  1.     TITLE 'LXB--BIOS extension loader'
  2.     PAGE 62
  3.  
  4. ;9/20/86--N.T.Carnevale
  5. ;After C.Sondgeroth's XLOAD--see Micro/Systems Journal vol.1 #2 p.66 et seq.
  6. ;See also my article in the July/August 1986 issue of M/S J pp.72-85.
  7. ;Modified 7/12/85 by NTC for new xbios called nuxb
  8.  
  9.  
  10. TRUE    EQU    0FFH
  11. FALSE    EQU    NOT TRUE
  12.  
  13. INTRUP    EQU    FALSE    ;TRUE if your hardware uses interrupts routinely
  14.  
  15.  
  16. HDRLNTH EQU    20H    ;# of bytes in the xbios's constant-length header
  17.  
  18.  
  19. BOOT    EQU    0    ;warm boot entry
  20. BDOS    EQU    5
  21. FCB    EQU    5CH    ;default fcb
  22.  
  23. CONOUT    EQU    2    ;console output func
  24. OPEN    EQU    15    ;bdos open file
  25. READ    EQU    20    ;     read sequential
  26. SETDMA    EQU    26    ;     set dma addr
  27.  
  28. CR    EQU    0DH
  29. LF    EQU    0AH
  30.  
  31.  
  32.     ORG 100H
  33.  
  34. XLOAD    EQU $
  35.     LXI H,0
  36.     DAD SP
  37.     SHLD STACK    ;saves stack pointer
  38.     LXI SP,STACK    ;& creates local stack
  39.     LDA FCB+1
  40.     CPI ' '     ;check for name of bios extension (xbios) file
  41.     JNZ XL20
  42.     CALL MSG
  43.     DB 'USAGE:  lxb filnam',CR,LF
  44.     DB '  where filnam is a bios extension file',CR,LF
  45.     DB '  (.SPR extension assumed)'
  46.     DB 0
  47. CPM$EXIT:
  48.     LHLD STACK
  49.     SPHL        ;restore stack pointer
  50.     RET        ;& bail out
  51.  
  52.  
  53. XL20:    LXI H,FCB+9    ;here starts file type
  54.     MVI M,'S'    ;force .SPR extension
  55.     INX H
  56.     MVI M,'P'
  57.     INX H
  58.     MVI M,'R'
  59.     INX H
  60.     MVI C,24    ;# of bytes remaining in fcb
  61. SLCLR:    MVI M,0     ;clear the rest of the fcb to nulls
  62.     INX H
  63.     DCR C
  64.     JNZ SLCLR
  65.     LXI D,FCB
  66.     MVI C,OPEN
  67.     CALL BDOS    ;open the xbios file
  68.     ANA A
  69.     JP SL50     ;if successful
  70.     CALL MSG    ;else say failed
  71.     DB 'unable to find the bios extension file'
  72.     DB 0
  73.     JMP CPM$EXIT
  74.  
  75.  
  76. ;Read the bios extension file into low memory
  77. SL50:    LXI H,BUF    ;hl = dma addr
  78. SL60:    PUSH H
  79.     XCHG        ;de = dma addr
  80.     MVI C,SETDMA
  81.     CALL BDOS    ;tell cpm where to put next sector
  82.     LXI D,FCB
  83.     MVI C,READ    ;read next sector
  84.     CALL BDOS
  85.     POP H
  86.     LXI D,128
  87.     DAD D        ;hl = next dma addr
  88.     ANA A
  89.     JZ SL60     ;not finished
  90.  
  91.  
  92. ;Relocate the .SPR file's contents to high memory (just below
  93. ;ccp, or below the last xbios module)
  94. IF    INTRUP
  95.     DI
  96. ENDIF
  97.     LDA BOOT+2    ;calc page of ccp
  98.     SUI 16H
  99.     MOV H,A     ;hl = ccp base page addr
  100.     LDA BDOS+2    ;current bdos page addr
  101.     CMP H
  102.     JNC REL1    ;if no prior xbios
  103.     LHLD BDOS+1    ;else get current top of tpa
  104. REL1:    MVI L,0     ;start on a page boundary
  105.     XCHG        ;de = 1+ top of tpa
  106.     LXI H,BUF+1    ;hl points to length of spr code
  107.     MOV C,M
  108.     INX H
  109.     MOV B,M     ;bc = length of spr code
  110.     PUSH B
  111.     INR C        ;round bc up to an integral # of pages
  112.     DCR C        ;if c = 0, code ends on a page boundary
  113.     JZ REL2
  114.     INR B
  115. REL2:    MOV A,D     ;calc where to move the code, put result in de
  116.     SUB B        ;a = bios page
  117.     STA XBPAGE    ;for future use
  118.     MOV D,A
  119.     MVI E,0     ;de = 1 + top of current tpa - code length
  120.     LXI H,BUF+256    ;start of relocatable code
  121.     POP B
  122.     PUSH B        ;bc = actual length of spr code
  123.     PUSH D        ;de = where to move it to (start of xbios)
  124.     CALL MOVEM    ;first move it up without relocation
  125.  
  126.     POP D        ;de = start of xbios
  127.     LXI H,BUF+256    ;hl = start of relocatable code
  128.     POP B        ;bc = length "
  129.     DAD B        ;hl = start of bit map
  130.  
  131.     PUSH D        ;save page offset
  132.     XCHG        ;hl = addr of code, de = addr of bit map
  133.     PUSH B        ;save byte count
  134.  
  135.  
  136. ;Get the next bit map byte and use it to direct relocation of 8 bytes
  137. ;Stop when end of relocatable code is found
  138. RELNMAP:
  139.     MVI C,8
  140.     LDAX D
  141.     MOV B,A     ;b = map byte
  142.     INX D        ;point to next map byte
  143. ;Shift & test relocation bits.
  144. ;If bit is 0, don't alter code, else add offset for new base addr
  145. RELNBYT:
  146.     DCR C        ;count bits in the byte
  147.     JM RELNMAP    ;get next byte
  148.     MOV A,B
  149.     RAL        ;get next bit
  150.     MOV B,A
  151.     JNC NOREL
  152.     LDA XBPAGE    ;offset
  153.     ADD M        ;add offset to code
  154.     MOV M,A
  155. NOREL:    INX H        ;next location to consider
  156.     XTHL        ;hl = byte count
  157.     DCX H
  158.     MOV A,H
  159.     ORA L        ;done?
  160.     XTHL        ;hl = code pointer again
  161.     JNZ RELNBYT    ;no, keep working
  162.  
  163.  
  164. ;After done with relocation:
  165. ;1.  fetch the original bios jump table and save a copy of it 
  166. ;    in the new xbios module
  167. ;2.  modify the original bios jump table so it points to the 
  168. ;    corresponding locations in the xbios's jump table
  169.     POP B        ;remove counter from the stack
  170.     POP H        ;hl = start of new bios module
  171.     PUSH H
  172. ;Next section is for new xbios--NTC
  173. ;Copy original bios jmp table into xbios at OLDTBL
  174.     INX H
  175.     INX H
  176.     INX H    
  177.     ;m = length of strings between end of header and start of jmp table
  178.     PUSH H        ;save place in the xbios header
  179.     MOV A,M
  180.     ADI HDRLNTH    ;a = distance from start of xbios to start of jmp table
  181.     MOV L,A     ;hl points to start of strings
  182.     XCHG        ;de is addr of xbios's copy of orig jmp table (dest)
  183.     POP H        ;return to xbios preface for more
  184.     INX H
  185.     MOV A,M     ;# of jmp instr in the table (omits jmp cold)
  186.     STA JMPNUM    ;for future use
  187.     ADD M
  188.     ADD M        ;a = length of jmp table in bytes (omitting jmp cold)
  189.     MOV C,A
  190.     MVI B,0     ;bc = # of bytes to copy
  191.     LHLD BOOT+1    ;hl = addr of 1st jmp to copy from bios table
  192.     CALL MOVEM    ;copy orig bios jmp table into oldtbl in xbios
  193.     LHLD BOOT+1    ;hl = addr of jmp wboot in orig bios table
  194.     LDA JMPNUM
  195.     MOV C,A     ;# of jmp instr to patch
  196. ;Now ready to patch the original jmp table to point to xbios's own table
  197. ;
  198. NEWJMP: INX H        ;patch old jmp table to point to 
  199.     MOV M,E     ;corresponding entries in xbios
  200.     INX H
  201.     MOV M,D
  202.     INX H
  203.     INX D
  204.     INX D
  205.     INX D        ;point to next entry addr in xbios jmp table
  206.     DCR C
  207.     JNZ NEWJMP    ;to finish fixing the old jmp table
  208.     POP D
  209.     PUSH D        ;de = addr of xbios
  210.     LHLD BDOS+1    ;hl = destination of old bdos jmp (bdos entry)
  211.     PUSH H        ;saved on stack
  212.     LXI H,BDOS+1    ;hl = where to patch the jmp to the xbios
  213.     MOV M,E
  214.     INX H
  215.     MOV M,D     ;now location 5 contains "jmp xbios"
  216.     POP B        ;bc = old bdos entry
  217.     POP H        ;hl = start of xbios
  218.     INX H
  219.     MOV M,C
  220.     INX H
  221.     MOV M,B     ;now first jmp in xbios is "jmp bdos"
  222. IF    INTRUP
  223.     EI
  224. ENDIF
  225.     RST 0        ;cp/m warm boot
  226.  
  227.  
  228. ;Send inline message, terminated by null, to console
  229. ;hl must point to the message
  230. MSG    EQU $
  231.     POP H
  232.     MOV A,M     ;a = next char
  233.     INX H
  234.     PUSH H
  235.     ANA A
  236.     RZ
  237.     MOV E,A
  238.     MVI C,CONOUT
  239.     CALL BDOS
  240.     JMP MSG
  241.  
  242.  
  243. MOVEM:    MOV A,M     ;move bc bytes from hl to de
  244.     STAX D
  245.     INX H
  246.     INX D
  247.     DCX B
  248.     MOV A,B
  249.     ORA C
  250.     JNZ MOVEM
  251.     RET
  252.  
  253.  
  254. JMPNUM: DS 1        ;will hold # of jmps in the bios jmp table
  255. XBPAGE: DS 1        ;will hold page addr of xbios
  256.  
  257.     DS 64
  258. STACK:    DS 2
  259.  
  260. BUF    EQU $        ;spr file goes here first
  261.  
  262.     END
  263.